'use strict';

module.exports = app => {
  class OrderController extends app.Controller {
    async list (ctx) {
      let me = await ctx.helper.rest.fetchMe({ctx})
      if (!me) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.UNLOGINED})
      }

      if (!ctx.is_self_admin) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.FORBIDDEN})
      }

      let { offset = 0, size = 10 } = ctx.request.query || {}
      offset = parseInt(offset)
      size = parseInt(size)

      let [error] = ctx.app.validator.validate({
        offset: ctx.validation.offset,
        size: ctx.validation.size
      }, {offset, size}) || []

      if (ctx.helper.abortOnError({ctx, error})) {
        return
      }

      let list = await ctx.model.order.find().skip(offset).limit(size)
      let total = await ctx.model.order.find().count()

      ctx.helper.rest.resp({
        ctx,
        data: {
          total,
          list: list.map(x => x.toObject({
            virtuals: true,
            transform: (doc, ret) => {
              ret = ctx.helper.mongoose.tranformId(doc, ret)
              ret = ctx.helper.mongoose.tranformTime(doc, ret)
              return ret
            }
          }))
        }
      })
    }

    async show (ctx) {
      let me = await ctx.helper.rest.fetchMe({ctx})
      if (!me) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.UNLOGINED})
      }

      if (!ctx.is_self_admin) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.FORBIDDEN})
      }
      // TODO: checkif administrator

      // start find it
      let { order_id } = ctx.params || {}
      if (!order_id) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.INVALID_PARAMS, message: 'order_id required.'})
      }

      let result = await ctx.app.model.order.findOne({_id: order_id})

      if (!result) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.NOT_FOUND})
      }

      ctx.helper.rest.resp({
        ctx,
        data: result.toJSON({transform: (doc, ret) => {
          ret = ctx.helper.mongoose.tranformId(doc, ret)
          ret = ctx.helper.mongoose.tranformTime(doc, ret)
          return ret
        }})
      })
    }

    async create (ctx) {

    }

    async update (ctx) {
      let me = await ctx.helper.rest.fetchMe({ctx})
      if (!me) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.UNLOGINED})
      }

      if (!ctx.is_self_admin) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.FORBIDDEN})
      }

      let { order_id } = ctx.params || {}
      if (!order_id) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.INVALID_PARAMS, message: 'order_id required.'})
      }

      let { app_link, email_addr, keywords, price, need, campaign_manager_name, status, target_country, title } = ctx.request.body
      price = parseFloat(price)
      if (isNaN(price)) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.INVALID_PARAMS, message: 'price should be one number.'})
      }

      let notEmpty = app_link || email_addr || keywords || price || need || campaign_manager_name || status || target_country || title

      if (!notEmpty) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.INVALID_PARAMS, message: 'update param required.'})
      }

      let [error] = ctx.app.validator.validate({
        // order_id
        app_link: {type: 'url', required: false, message: 'app_link should be one url string.'},
        email_addr: {type: 'email', required: false},
        keywords: {type: 'string', required: false, allowEmpty: true},
        campaign_manager_name: {type: 'string', required: false, allowEmpty: true, max: 108},
        status: {type: 'string', enum: ctx.CONST.order.statusEnum},
        price: {type: 'number', required: false, min: 0},
        need: {type: 'string', required: false, allowEmpty: true},
        target_country: {type: 'string', required: false},
      }, {app_link, email_addr, keywords, price, need, campaign_manager_name, status, target_country, title}) || []

      if (ctx.helper.abortOnError({ctx, error})) {
        return
      }

      let update = {app_link, email_addr, keywords, price, need, campaign_manager_name, status, target_country, title}
      update = JSON.parse(JSON.stringify(update))

      let result = await ctx.app.model.order.findOneAndUpdate({_id: order_id}, {
        $set: update
      })

      if (!result) {
        return ctx.helper.abortOnError({ctx, error: ctx.errors.UPDATE_FAIL})
      }

      ctx.helper.rest.resp({ctx, message: 'update success.'})
    }
  }

  return OrderController
}
